import java.io.*;
import java.util.*;



public class PLFile<RecordTypeT> {
	protected String mFileName;
	protected ArrayList<RecordTypeT> mRecords;
	protected int mLastRead;	

	public PLFile() {
		mLastRead = 0;		
		mRecords = new ArrayList<RecordTypeT>();
	}

	public PLFile(String filename) {
		mLastRead = 0;
		SetFileName(filename);
		
		mRecords = new ArrayList<RecordTypeT>();
	}

	public void SetFileName(String inFilename) {
		mFileName = inFilename;
	}
	public String GetFileName() {
		return mFileName;
	}

	public void BeginRead() { 
		if (mRecords.isEmpty()) {
			ReadFile();
		}
		mLastRead = 0;
	}

	public RecordTypeT GetNextRecord() {
		if (mRecords.isEmpty()) {
			ReadFile();
		}
		
		if (mLastRead >= mRecords.size() )
			return null;
		RecordTypeT outRecord = (RecordTypeT) mRecords.get(mLastRead);

		mLastRead++;

		return outRecord;
	}

	public RecordTypeT GetRecordAt(int index) {
		if (mRecords.isEmpty()) {
			ReadFile();
		}
		
		if (index >= mRecords.size())
			return null;
		RecordTypeT outRecord = (RecordTypeT) mRecords.get(index);

		return outRecord;
	}


	public int GetNumOfRecords() {return mRecords.size();}

	public ArrayList<RecordTypeT> GetAllRecords() {return mRecords;}		

	@SuppressWarnings("unchecked")
	protected void ReadRecordsFromInputStream(ObjectInputStream ois){ 
		try{
			mRecords = (ArrayList<RecordTypeT>) ois.readObject();
		}catch(IOException e){
			e.printStackTrace();
		}catch(ClassNotFoundException e){
			e.printStackTrace();
		}		
	}


	public boolean WriteRecord(RecordTypeT record) {
		mRecords.add(record);
		return true;
	}

	public void FinishedWriting() {
		WriteFile();
	}

	protected void WriteRecordsToOutputStream(ObjectOutputStream oos){ 
		try{
			oos.writeObject(mRecords); 
		}catch(IOException e){
			e.printStackTrace();
		}		
	}

	// PROTECTED METHODS

	// reads the records from the file
	protected boolean ReadFile() {
		boolean result = false;
		try{
			FileInputStream fis = new FileInputStream(GetFileName());
			ObjectInputStream ois = new ObjectInputStream(fis);
			ReadRecordsFromInputStream(ois);
			ois.close();		
			result = true;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch(IOException e){
			e.printStackTrace();
		}
		return result;
	}
	
	// writes the records to the file
	protected boolean WriteFile() {
		boolean result = false;
		try {
			FileOutputStream fos = new FileOutputStream(GetFileName());
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			WriteRecordsToOutputStream(oos);
			oos.flush();
			oos.close();
			result = true;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch(IOException e){
			e.printStackTrace();
		}		
		return result;
	}
}


